#include "programrun.h"
#include "PlugIn_Base.h"
#include "PlugInList.h"
#include <QMessageBox>


ProGramRunThread::ProGramRunThread(quint32 rowtotal, QList <T_program_Unit > tProgram,QObject *parent)
:QThread(parent)
,stopFlag(0)
{
    _lastRowIndex = 0;
    _rowindex = 0;
    _rowtotal = rowtotal;
    _JsonList = tProgram;
    qDebug()<<_JsonList.size();
}

ProGramRunThread::~ProGramRunThread(void)
{
    qDebug()<<__func__;
}

void ProGramRunThread::ProGramStop(void)
{
    stopFlag = 1;
}

void ProGramRunThread::setErrRetFlag(quint8 flag)
{
    sigFailRet = flag;
}

void ProGramRunThread::onDealRun(void)
{
    QElapsedTimer timer;
    timer.start();
    qint64 elapsed = timer.elapsed();
    while(!stopFlag)
    {
        if( timer.elapsed() - elapsed >= 1000)
        {
            elapsed = timer.elapsed();
            qDebug()<<"elapsed:"<<elapsed;

            emit sigRowSta(_lastRowIndex,E_STA_NONE);
            emit sigRowSta(_rowindex,E_STA_RUNNING);
            /*
            if(!_JsonList[_rowindex].JsonObj.isEmpty())
            {
                 qDebug()<<_JsonList[_rowindex].JsonObj;
                 QJsonObject retJson =  PlugInRun(_JsonList[_rowindex].StrCmd,_JsonList[_rowindex].JsonObj);
                 sPlugInJudge(_rowindex,retJson);
            }
            */

            emit sigFailSet("失败测试");
            sigFailRet = E_RUN_ERR_FLAG_NULL;
            while(sigFailRet == E_RUN_ERR_FLAG_NULL)
            {
                QCoreApplication::processEvents(QEventLoop::AllEvents); ;
            }
             elapsed = timer.elapsed();



            _lastRowIndex = _rowindex;
            _rowindex = (_rowindex + 1)%_rowtotal;
        }
    }
}


QJsonObject ProGramRunThread::PlugInRun(QString Label,QJsonObject qjson)
{
    qDebug()<<"size"<<PlugInList::getInstance()->GetPlugInNum()  ;
    qDebug()<<"Label"<<Label;

    for(quint32 i = 0;i < PlugInList::getInstance()->GetPlugInNum();i++)
    {
        if(PlugInList::getInstance()->GetPlug(i)->GetLable() == Label)
        {
            qDebug()<<"GetLable:"<<PlugInList::getInstance()->GetPlug(i)->GetLable() ;
            QJsonObject RetJson = PlugInList::getInstance()->GetPlug(i)->StartRun(qjson);

            qDebug()<<"ret: "<<RetJson;
            return RetJson;

        }
    }
}

void ProGramRunThread::sPlugInJudge(quint32 row,QJsonObject obj)
{
    //RetJson格式 ：
    //("failreason",""); //失败原因 如果是空 则成功 如果是失败  则失败 显示原因就好了
    //("runvalue",strretvalue); string int uint float hex bool
    //("runvalue_type","str");

    QString strFail     = obj["failreason"].toString();
    QString QStrType = obj["runvalue_type"].toString();
    QString strRetValue ;
    if(strFail.isEmpty())//结束原因为空 则为成功
    {

        if(QStrType == "string")
        {
            strRetValue = obj["runvalue"].toString();
        }
        else if(QStrType == "int")
        {
            qint32 Value = obj["runvalue"].toInt();
            strRetValue = QString::number(Value,10);

        }
        else if(QStrType == "uint")
        {
            quint32 Value = obj["runvalue"].toInt();
            strRetValue = QString::number(Value,10);
        }
        else if(QStrType == "float")
        {
            float Value = obj["runvalue"].toDouble();
            strRetValue = QString::number(Value,'f',5);
        }
        else if(QStrType == "hex")
        {
            quint32 Value = obj["runvalue"].toInt();
            strRetValue = QString::number(Value,16);
        }
        else if(QStrType == "bool")
        {
            bool Value = obj["runvalue"].toBool();
            strRetValue = QString::number(Value,16);
        }
        //设置值
        if(_JsonList[row].StrLevelUpper == _JsonList[row].StrLevelLower)//上限值等于下限值 //那就比对值相不相等
        {
            if(strRetValue != _JsonList[row].StrLevelUpper)//失败
            {
               //设置失败提示框
            }
            else //成功
            {
              //显示绿色
            }
        }
        else//上下限不相等
        {
           //只有hex和 uint int 可以转换 其他不行
            if(QStrType != "int"
               && QStrType != "uint"
               && QStrType != "float"
               && QStrType != "hex")

           {
                //错误
           }
           else
          {
              if(QStrType == "int")
              {
                  qint32 Value = obj["runvalue"].toInt();
                  quint8 ret =    Compare_int(_JsonList[row].StrLevelUpper   ,_JsonList[row].StrLevelLower, Value);
              }
              else if (QStrType != "uint")
              {
                  qint32 Value = obj["runvalue"].toInt();
                  quint8  ret =   Compare_uint(_JsonList[row].StrLevelUpper  ,_JsonList[row].StrLevelLower, Value);
              }
              else if(QStrType != "float")
              {
                  float Value = obj["runvalue"].toDouble();
                  quint8   ret =  Compare_float(_JsonList[row].StrLevelUpper , _JsonList[row].StrLevelLower,Value);
              }
              else if(QStrType != "hex")
              {
                  quint32 Value = obj["runvalue"].toInt();
                  quint8   ret =  Compare_hex(_JsonList[row].StrLevelUpper   , _JsonList[row].StrLevelLower,Value);
              }
          }

        }
    }
    else
    {
      //emit sigFailSet(strFail);
      //while(等待返回)
      //{

      //}
        //等待
    }
    //RetJson 里面有返回值和返回类型
    //如果上限值和下限值 相等 转换成相应的值 判断是否相等
    //如果不相等
    // 查看返回值类型 string int8 uint8 int16 uint16 int32 uint32 float hex
    //然后把上限值和下限值转换
    //再对比大小
}

quint8 ProGramRunThread::Compare_int(QString Upper,QString Lower,qint32 Value)
{
    qint32 valueUpper = Upper.toInt();
    qint32 valueLower = Lower.toInt();
    if(Value <= valueUpper && Value>= valueLower)
    {
        return 1;
    }
    return 0;

}
quint8 ProGramRunThread::Compare_uint(QString Upper,QString Lower,quint32 Value)
{
    quint32 valueUpper = Upper.toUInt();
    quint32 valueLower = Lower.toUInt();

    if(Value <= valueUpper && Value>= valueLower)
    {
        return 1;
    }
    return 0;
}
quint8 ProGramRunThread::Compare_float(QString Upper,QString Lower,quint32 Value)
{
    float valueUpper = Upper.toFloat();
    float valueLower = Lower.toFloat();
    if(Value <= valueUpper && Value>= valueLower)
    {
        return 1;
    }
    return 0;
}
quint8 ProGramRunThread::Compare_hex(QString Upper,QString Lower,quint32 Value)
{
    qint32 valueUpper = Upper.toUInt(0,16);
    qint32 valueLower = Lower.toUInt(0,16);
    if(Value <= valueUpper && Value >= valueLower)
    {
        return 1;
    }
    return 0;
}

ProGramRun::ProGramRun(QWidget *parent )
:QWidget(parent)
,_ui(new Ui::ProgramRun)
,_ProThread(0)
,_thread(0)
,_err(0)
{
    _ui->setupUi(this);
    setWindowTitle("运行窗口");

    _err = new RunErr();
    connect(_err,     SIGNAL(SigEvent(quint8)),this,SLOT(onDealErrRet(quint8)));

    connect(_ui->pb_begin,     SIGNAL(clicked()),this,SLOT(onDealBegin()));
}

void ProGramRun::ProGramRum_Add(T_program_Unit *pUnit)
{
    T_program_Unit TmpUnit = {0};
    memcpy((uint8_t *)&TmpUnit,(uint8_t *)pUnit,sizeof(T_program_Unit));
    tProgram.append(TmpUnit);

    quint32 rownums = _ui->tableWidget->rowCount();
    _ui->tableWidget->insertRow(rownums);

    QTableWidgetItem *item0 = new QTableWidgetItem();
    item0->setFlags(Qt::ItemIsEnabled); // 设置单元格为不可编辑，但可交互
    item0->setText(pUnit->StrFlag);
    _ui->tableWidget->setItem(rownums,0,item0);

    QTableWidgetItem *item1 = new QTableWidgetItem();
    item1->setFlags(Qt::ItemIsEnabled); // 设置单元格为不可编辑，但可交互
    item1->setText(pUnit->StrCmd);
    _ui->tableWidget->setItem(rownums,1,item1);

    QTableWidgetItem *item2 = new QTableWidgetItem();
    item2->setFlags(Qt::ItemIsEnabled); // 设置单元格为不可编辑，但可交互
    item2->setText(pUnit->StrDetail);
    _ui->tableWidget->setItem(rownums,2,item2);

    QTableWidgetItem *item3 = new QTableWidgetItem();
    item3->setFlags(Qt::ItemIsEnabled); // 设置单元格为不可编辑，但可交互
    item3->setText(pUnit->StrLevelLower);
    _ui->tableWidget->setItem(rownums,3,item3);

    QTableWidgetItem *item4 = new QTableWidgetItem();
    item4->setFlags(Qt::ItemIsEnabled); // 设置单元格为不可编辑，但可交互
    _ui->tableWidget->setItem(rownums,4,item4);

    QTableWidgetItem *item5 = new QTableWidgetItem();
    item5->setFlags(Qt::ItemIsEnabled); // 设置单元格为不可编辑，但可交互
    item5->setText(pUnit->StrLevelUpper);
    _ui->tableWidget->setItem(rownums,5,item5);

    QTableWidgetItem *item6 = new QTableWidgetItem();
    item6->setFlags(Qt::ItemIsEnabled); // 设置单元格为不可编辑，但可交互
    item6->setText(pUnit->StrUnit);
    _ui->tableWidget->setItem(rownums,6,item6);

    QTableWidgetItem *item7 = new QTableWidgetItem();
    item7->setFlags(Qt::ItemIsEnabled); // 设置单元格为不可编辑，但可交互
    //item7->setText(pUnit->StrUnit);
    _ui->tableWidget->setItem(rownums,7,item7);

    QTableWidgetItem *item8 = new QTableWidgetItem();
    item8->setFlags(Qt::ItemIsEnabled); // 设置单元格为不可编辑，但可交互
    //item8->setText(pUnit->StrUnit);
    _ui->tableWidget->setItem(rownums,8,item8);

    for(uint32_t i = 0;i < _ui->tableWidget->columnCount();i++)
    {
        QTableWidgetItem *item = _ui->tableWidget->item(rownums,i);
        if(item)
            item->setTextAlignment(Qt::AlignCenter);//文本居中
    }
}

void ProGramRun::closeEvent(QCloseEvent *ev)
{
    qDebug()<<__func__;
    if(!_ProThread || !_thread)
        return ;
    _ProThread->ProGramStop();
    _thread->quit();
    _thread->wait();

    _thread->deleteLater();
    _thread = 0;

}
void ProGramRun::onDealBegin(void)
{
    quint32 rownums = _ui->tableWidget->rowCount();

    _ProThread = new ProGramRunThread(rownums,tProgram);
    _thread    = new QThread();
    //调用moveToThread将该任务交给workThread
    _ProThread->moveToThread(_thread);
    //operate信号发射后启动线程工作
    connect(_ProThread,    SIGNAL(sigRowSta(quint32,quint8)), this,       SLOT(onDealRowStaSet(quint32,quint8)));
    connect(this,          SIGNAL(operate()),                 _ProThread, SLOT(onDealRun()));
     connect(_ProThread,   SIGNAL(sigFailSet(QString)),       this,       SLOT(onDealSetFailReason(QString)));
    //该线程结束时销毁
    connect(_thread, &QThread::finished, _ProThread, &QObject::deleteLater);
    //线程结束后发送信号，对结果进行处理
    //connect(worker, SIGNAL(resultReady(int)), this, SLOT(handleResults(int)));
    //启动线程

    _thread->start();
    //发射信号，开始执行
    emit operate();
}

void ProGramRun::onDealRowStaSet(quint32 Row,quint8 sta)
{
    if(sta == E_STA_NONE)
    {
        for(uint32_t i = 0;i < _ui->tableWidget->columnCount();i++)
        {
            QTableWidgetItem *item = _ui->tableWidget->item(Row,i);
            if(item)
                item->setBackground(Qt::transparent);
        }
    }
    else if(sta == E_STA_RUNNING)
    {
        for(uint32_t i = 0;i < _ui->tableWidget->columnCount();i++)
        {
            QTableWidgetItem *item = _ui->tableWidget->item(Row,i);
            if(item)
                item->setBackground(Qt::yellow);
        }
    }
    else if(sta == E_STA_FAIL)
    {
        for(uint32_t i = 0;i < _ui->tableWidget->columnCount();i++)
        {
            QTableWidgetItem *item = _ui->tableWidget->item(Row,i);
            if(item)
                item->setBackground(Qt::red);
        }
    }
    else if(sta == E_STA_SUCC)
    {
        for(uint32_t i = 0;i < _ui->tableWidget->columnCount();i++)
        {
            QTableWidgetItem *item = _ui->tableWidget->item(Row,i);
            if(item)
                item->setBackground(Qt::green);
        }
    }
}

void ProGramRun::onDealSetFailReason (QString str)
{
    _err->SetTitle("错误");
    _err->SetDetail(str);
    _err->show();
}


void ProGramRun::onDealErrRet(quint8 flag)
{
    _err->hide();
    if(_ProThread)
        _ProThread->setErrRetFlag(flag);
}
